package com.zrf.gulimall.commnon.core.exception;

import cn.hutool.core.map.MapUtil;
import com.zrf.gulimall.commnon.core.response.Resp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.yaml.snakeyaml.constructor.DuplicateKeyException;

import java.util.Map;

/**
 * 全局异常处理器
 *
 * @author zhanrf
 */
@RestControllerAdvice
public class GlobalExceptionHandler {
  private final Logger logger = LoggerFactory.getLogger(getClass());

  /**
   * 处理自定义异常
   */
  @ExceptionHandler(CustomException.class)
  public Resp<Void> handleCustomException(CustomException e) {
    logger.error(e.getMsg(), e);
    return Resp.error(e.getCode(), e.getMessage());
  }

  @ExceptionHandler(NoHandlerFoundException.class)
  public Resp<Void> handlerNoFoundException(Exception e) {
    logger.error(e.getMessage(), e);
    return Resp.error(404, "路径不存在，请检查路径是否正确");
  }

  @ExceptionHandler(DuplicateKeyException.class)
  public Resp<Void> handleDuplicateKeyException(DuplicateKeyException e) {
    logger.error(e.getMessage(), e);
    return Resp.error("数据库中已存在该记录");
  }

  @ExceptionHandler(MethodArgumentNotValidException.class)
  public Resp<Map<String, String>> methodArgumentNotValidException(MethodArgumentNotValidException e) {
    logger.error(e.getMessage(), e);
    BindingResult bindingResult = e.getBindingResult();
    Map<String, String> errorMap = MapUtil.newHashMap();
    bindingResult.getFieldErrors().forEach(item -> errorMap.put(item.getField(), item.getDefaultMessage()));
    return Resp.<Map<String, String>>error(StatusCode.INVALID_EXCEPTION.getCode(), StatusCode.INVALID_EXCEPTION.getMsg()).setData(errorMap);
  }

  @ExceptionHandler(Exception.class)
  public Resp<Void> handleException(Exception e) {
    logger.error(e.getMessage(), e);
    return Resp.error(StatusCode.UN_KNOW_EXCEPTION.getCode(), StatusCode.UN_KNOW_EXCEPTION.getMsg());
  }
}
